package com.bobbygu.bobbyapp.base;

import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;
import com.bobbygu.lib.mvvm.common.BaseModel;
import com.bobbygu.lib.mvvm.common.BaseViewModel;
import com.bobbygu.libnet.baserx.RxManager;
import com.bobbygu.libnet.baserx.RxSchedulers;
import com.bobbygu.libnet.bean.DataResponse;
import com.bobbygu.libnet.common.Api;
import com.bobbygu.libnet.common.HostType;
import com.bobbygu.libnet.common.ResponseFunc;

import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;

/**
 * MyBaseM
 * <p>
 * author: 顾博君 <br>
 * time:   2017/10/19 14:55 <br>
 * e-mail: gubojun@csii.com.cn <br>
 * </p>
 */

public class MyBaseM<VM extends BaseViewModel> extends BaseModel<VM> {
    protected RxManager mRxManager;

    public void init(RxManager rxManager) {
        mRxManager = rxManager;
    }

    public void post(String action, Map<String, String> params,
                     final SuccessCallBack successCallBack,
                     final ErrorCallBack errorCallBack) {
        post(params == null ?
                Api.getDefault().postAction(action) :
                Api.getDefault().postAction(action, params), new Consumer<JSONObject>() {
            @Override
            public void accept(@NonNull JSONObject jsonObject) throws Exception {
                if (successCallBack != null)
                    successCallBack.onSuccess(jsonObject);
            }
        }, new ErrorConsumer() {
            @Override
            protected void onError(String errMsg, String errCode) {
                if (errorCallBack != null)
                    errorCallBack.onError(errMsg, errCode);
                else
                    Toast.makeText(MyApplication.getInstance(), errMsg, Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void post(String action,
                     final SuccessCallBack successCallBack,
                     final ErrorCallBack errorCallBack) {
        post(action, null, successCallBack, errorCallBack);
    }

    public void postUpload(RequestBody description, Map<String, RequestBody> params,
                           final SuccessCallBack successCallBack,
                           final ErrorCallBack errorCallBack) {
        post(Api.getDefault().upload(description, params), new Consumer<JSONObject>() {
            @Override
            public void accept(JSONObject jsonObject) throws Exception {
                if (successCallBack != null)
                    successCallBack.onSuccess(jsonObject);
            }
        }, new ErrorConsumer() {
            @Override
            protected void onError(String errMsg, String errCode) {
                if (errorCallBack != null)
                    errorCallBack.onError(errMsg, errCode);
                else
                    Toast.makeText(MyApplication.getInstance(), errMsg, Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 返回类型为Observable<ResponseBody>
     */
    public void postRB(String action, Map<String, String> params,
                       final SuccessRBCallBack successCallBack,
                       final ErrorCallBack errorCallBack) {
        postMethod(Api.getDefault().postResponseBody(action, params), new Consumer<ResponseBody>() {
            @Override
            public void accept(ResponseBody responseBody) throws Exception {
                if (successCallBack != null)
                    successCallBack.onSuccess(responseBody);
            }
        }, new ErrorConsumer() {
            @Override
            protected void onError(String errMsg, String errCode) {
                if (errorCallBack != null)
                    errorCallBack.onError(errMsg, errCode);
                else
                    Toast.makeText(MyApplication.getInstance(), errMsg, Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void postDownload(String url,
                             final SuccessRBCallBack successCallBack,
                             final ErrorCallBack errorCallBack,
                             final OnProgressListener onProgressListener) {

        postMethod(Api.getDefault(HostType.DOWNLOAD_HOST).postDownload(url), new Consumer<ResponseBody>() {
            @Override
            public void accept(ResponseBody responseBody) throws Exception {
                if (successCallBack != null)
                    successCallBack.onSuccess(responseBody);
            }
        }, new ErrorConsumer() {
            @Override
            protected void onError(String errMsg, String errCode) {
                if (errorCallBack != null)
                    errorCallBack.onError(errMsg, errCode);
                else
                    Toast.makeText(MyApplication.getInstance(), errMsg, Toast.LENGTH_SHORT).show();
            }
        });
        Api.getApi(HostType.DOWNLOAD_HOST).setProgressListener(new Api.ProgressListener() {
            @Override
            public void onResponseProgress(long bytesRead, long contentLength, boolean done) {
                onProgressListener.downloadProgress(bytesRead, contentLength, done);
            }
        });
    }

    private void post(Observable<DataResponse<JSONObject>> observable,
                      final Consumer<JSONObject> successConsumer, final ErrorConsumer errorConsumer) {
        ResponseFunc<JSONObject> responseFunc = new ResponseFunc<JSONObject>();
        postMethod(observable, successConsumer, errorConsumer, responseFunc);
    }

//    private void postRB(Observable<ResponseBody> observable,
//                        final Consumer<ResponseBody> successConsumer, final ErrorConsumer errorConsumer) {
//        postMethod(observable, successConsumer, errorConsumer);
//    }

    /**
     * @param observable   请求
     * @param rConsumer    正常返回
     * @param eConsumer    错误返回
     * @param responseFunc T类型数据转换为R类型数据
     * @param <T>          数据类型
     * @param <R>          数据类型
     * @since 1.1.1
     */

    private <T, R> void postMethod(Observable<T> observable, Consumer<R> rConsumer, Consumer<? super Throwable> eConsumer, Function<T, R> responseFunc) {
        if (observable != null)
            mRxManager.add(observable
                    .map(responseFunc)
                    .compose(RxSchedulers.<R>io_main())
                    .subscribe(rConsumer, eConsumer)
            );
    }

    private <T> void postMethod(Observable<T> observable, Consumer<T> rConsumer, Consumer<? super Throwable> eConsumer) {
        mRxManager.add(observable
                .compose(RxSchedulers.<T>io_main())
                .subscribe(rConsumer, eConsumer)
        );
    }

    public interface OnProgressListener {
        void downloadProgress(long bytesRead, long contentLength, boolean done);
    }

    public interface SuccessRBCallBack {
        void onSuccess(ResponseBody responseBody);
    }

    public interface SuccessCallBack {
        void onSuccess(@NonNull JSONObject jsonObject);
    }

    public interface ErrorCallBack {
        void onError(String errMsg, String errCode);
    }
}
